package com.example.demoddd.domain.userauth.filter;

import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONUtil;
import com.example.demoddd.config.JwtConfig;
import com.example.demoddd.domain.userauth.model.User;
import jakarta.servlet.FilterChain;
import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.security.authentication.InsufficientAuthenticationException;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.oauth2.core.OAuth2AuthenticationException;
import org.springframework.security.oauth2.jwt.Jwt;
import org.springframework.security.oauth2.jwt.JwtDecoder;
import org.springframework.web.filter.OncePerRequestFilter;

import java.io.IOException;

@RequiredArgsConstructor
@Slf4j
public class JwtAuthenticationFilter extends OncePerRequestFilter {
    private final JwtDecoder jwtDecoder;

    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
        log.debug("JwtAuthenticationFilter认证开始>>>>>>>");
        log.debug("JwtConfig.headerkeyName>>>{}", JwtConfig.headerkeyName);
        String jwtToken = request.getHeader(JwtConfig.headerkeyName);
        //System.out.println(JwtConfig.headerkeyName);

        // 如果token为空，则放行，继续处理下一个过滤器
        if (StrUtil.isBlankOrUndefined(jwtToken)) {
            filterChain.doFilter(request, response);
            return;
        }

        //如果token有值  解析获取声明
        Jwt jwt = jwtDecoder.decode(jwtToken);

        if (null == jwt) {
            throw new OAuth2AuthenticationException("token解析失败");
        }

        //判断过期  .decode 已经验证
        /*Instant expiresAt = jwt.getExpiresAt();
        if (Instant.now().isAfter(expiresAt)) {
            throw new OAuth2AuthenticationException("token过期");
        }*/

        //扩展其他  安全校验
        //刷新token接口的
        if ((!"/refreshToken".equals(request.getRequestURI())) && (!"TokenS".equals(jwt.getClaimAsString("tokenName")))) {
            //非刷新的接口  验证是短token
            throw new InsufficientAuthenticationException("token认证失败");
        }

        if (("/refreshToken".equals(request.getRequestURI())) && (!"TokenL".equals(jwt.getClaimAsString("tokenName")))) {     //刷新的接口  验证是长token
            //刷新的接口  验证是长token
            throw new InsufficientAuthenticationException("token认证失败");
        }

        //成功验证 放入上下文
        String subject = jwt.getSubject();
        User user = JSONUtil.toBean(subject, User.class);
        //使用UsernamePasswordAuthenticationToken.authenticated构建已认证的UsernamePasswordAuthenticationToken
        UsernamePasswordAuthenticationToken usernamePasswordAuthenticationToken = UsernamePasswordAuthenticationToken.authenticated(
                user, //jwt认证成功的 UserDetails
                user.getPassword(),
                user.getAuthorities() //权限
        );
        SecurityContextHolder.getContext().setAuthentication(usernamePasswordAuthenticationToken);

        //过
        filterChain.doFilter(request, response);
    }
}
